package com.boatAnchorAssistant.service.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.boatAnchorAssistant.pojo.entity.*;
import com.boatAnchorAssistant.pojo.enums.alarm.AlarmStatusEnum;
import com.boatAnchorAssistant.pojo.param.alarmPushLog.*;
import com.boatAnchorAssistant.pojo.vo.alarmPushLog.*;
import com.boatAnchorAssistant.pojo.dto.alarmPushLog.*;
import com.boatAnchorAssistant.service.repository.in.*;
import com.boatAnchorAssistant.service.service.in.AlarmPushLogService;
import nirvana.core.domains.vo.PageResult;
import nirvana.core.exceptions.BizException;
import nirvana.core.utils.ids.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 【描 述】：报警推送日志服务
 * 【环 境】：J2SE 17
 * 【详 细】：
 */
@Service
public class AlarmPushLogServiceImpl implements AlarmPushLogService {

    private final AlarmPushLogRepository alarmPushLogRepository;
    private final AlarmTypeRepository typeRepository;
    private final AlarmCauseRepository causeRepository;
    private final DataDictionaryRepository dictionaryRepository;
    private final EventGroupRepository eventGroupRepository;
    private final DeviceRepository deviceRepository;
    private final AlarmRepository alarmRepository;

    private Long levelTypeId=1856601692826247168L;
    private Long areaTypeId=1856594526006419456L;

    public AlarmPushLogServiceImpl(AlarmPushLogRepository alarmPushLogRepository, AlarmTypeRepository typeRepository, AlarmCauseRepository causeRepository, DataDictionaryRepository dictionaryRepository, EventGroupRepository eventGroupRepository, DeviceRepository deviceRepository, AlarmRepository alarmRepository) {
        this.alarmPushLogRepository = alarmPushLogRepository;
        this.typeRepository = typeRepository;
        this.causeRepository = causeRepository;
        this.dictionaryRepository = dictionaryRepository;
        this.eventGroupRepository = eventGroupRepository;
        this.deviceRepository = deviceRepository;
        this.alarmRepository = alarmRepository;
    }


    /**
     * 创建报警推送日志
     *
     * @param param
     */
    @Override
    public void createAlarmPushLog(CreateAlarmPushLogParam param) {
        AlarmPushLog alarmPushLog = new AlarmPushLog();
        BeanUtils.copyProperties(param, alarmPushLog);
        Long id = IdGenerator.SNOW.generate();
        alarmPushLog.setId(id);
        alarmPushLogRepository.create(alarmPushLog);
    }

    /**
     * 修改报警推送日志
     *
     * @param param
     */
    @Override
    public void editAlarmPushLog(EditAlarmPushLogParam param) {
        Long id = param.getId();
        AlarmPushLog alarmPushLog = alarmPushLogRepository.getByIdCheck(id);
        BeanUtils.copyProperties(param, alarmPushLog);
        alarmPushLogRepository.edit(alarmPushLog);
    }

    /**
     * 移除报警推送日志
     *
     * @param id
     */
    @Override
    public void removeAlarmPushLog(Long id) {
        alarmPushLogRepository.removeById(id);
    }

    /**
     * 启动/禁用报警推送日志
     *
     * @param id
     */
    @Override
    public void enabledAlarmPushLog(Long id) {
        AlarmPushLog alarmPushLog = alarmPushLogRepository.getByIdCheck(id);
        alarmPushLog.setIsDisable(!alarmPushLog.getIsDisable());
        alarmPushLogRepository.edit(alarmPushLog);
    }

    /**
     * 获取报警推送日志详情
     *
     * @param id
     * @return
     */
    @Override
    public GetAlarmPushLogVo getAlarmPushLog(Long id) {
        AlarmPushLog alarmPushLog = alarmPushLogRepository.getByIdCheck(id);
        GetAlarmPushLogVo vo = new GetAlarmPushLogVo();
        BeanUtils.copyProperties(alarmPushLog, vo);
        return vo;
    }

    /**
     * 获取报警推送日志 列表
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<GetAlarmPushLogListVo> getAlarmPushLogList(GetAlarmPushLogListParam param) {

        SelectAlarmPushLogDto dto = new SelectAlarmPushLogDto();
        BeanUtils.copyProperties(param, dto);
        Page<AlarmPushLog> page = alarmPushLogRepository.selectAlarmPushLog(dto);
        List<AlarmPushLog> alarmPushLogList = page.getRecords();
        List<GetAlarmPushLogListVo> list = new ArrayList<>();
        for (AlarmPushLog alarmPushLog : alarmPushLogList) {
            GetAlarmPushLogListVo vo = new GetAlarmPushLogListVo();
            BeanUtils.copyProperties(alarmPushLog, vo);

            list.add(vo);
        }
        return new PageResult<>(list, page);

    }

    /**
     * 获取报警推送日志下拉列表
     *
     * @param param
     * @return
     */
    @Override
    public List<GetAlarmPushLogDownListVo> getAlarmPushLogDownList(GetAlarmPushLogDownListParam param) {
        AlarmPushLog po = new AlarmPushLog();
        if (param != null) {
            BeanUtils.copyProperties(param, po);
        }
        List<AlarmPushLog> alarmPushLogList = alarmPushLogRepository.getListByEntity(po);

        List<GetAlarmPushLogDownListVo> list = new ArrayList<>();
        for (AlarmPushLog alarmPushLog : alarmPushLogList) {
            GetAlarmPushLogDownListVo vo = new GetAlarmPushLogDownListVo();
            BeanUtils.copyProperties(alarmPushLog, vo);
            list.add(vo);
        }
        return list;
    }


    /**
     * {
     *     "areaId" : 4, // 报警区域 数据字典
     *     "areaName" : "左侧舷梯", // 报警区域名称
     *     "camNo" : "23060022", // 设备编号
     *     "dutyLevel" : 1, // 值班等级
     *     "level" : 1, // 报警等级 数据字典
     *     "newalarm" : 1, // 是否新报警
     *     "picurl" : [
     *        "http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_1S.jpg",
     *        "http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_2S.jpg",
     *        "http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_3S.jpg"
     *     ],
     *     "reason" : 12, // 报警原因 数据字典
     *     "region" : 0, // 报警海域 枚举
     *     "remark" : "", // 备注
     *     "shipstatus" : 1, // 船舶状态 枚举
     *     "sid" : "e16ed3aec0a3a4f9", // 报警id
     *     "speed" : 9.8000001907348633, // 当前船速
     *     "stime" : "2024-11-18 09:19:17", // 报警时间
     *     "type" : 6, //报警类型
     *     "videourl" : "http://10.17.17.199:8008//10.17.17.199:8008//10.17.17.199:8008THE/data/Behavior/20241118/BECLOTHES/RS20241118091909071_14015e2e75a05fd2_A4_1R.jpg",
     *     "other" : {
     *         "_cog" : 222.69999999999999, // 船舶地面航向
     *         "_mmsi" : "413232470", // 船舶mmsi编号
     *         "_shipname" : "实验室测试", // 船舶名称
     *         "_sog" : 10.300000000000001, // 船舶相对地面速度
     *         "_trueheading" : 228, // 船头航向
     *         "myalrmlat" : 20.053874969482422, // 报警船舶纬度
     *         "myalrmlon" : 110.14382171630859, // 报警船舶经度
     *     }
     * }
     * @param json
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receiveAlarmPushLog(JSONObject json) {
        //处理json

        AlarmPushLog alarmPushLog = new AlarmPushLog();
        alarmPushLog.setId(IdGenerator.SNOW.generate());
        alarmPushLog.setAreaId(json.getStr("areaId"));
        alarmPushLog.setAreaName(json.getStr("areaName"));
        alarmPushLog.setCamNo(json.getStr("camNo"));
        alarmPushLog.setDutyLevel(json.getStr("dutyLevel"));
        alarmPushLog.setLevel(json.getStr("level"));
        alarmPushLog.setNewAlarm(json.getBool("newalarm"));
        alarmPushLog.setReason(json.getStr("reason"));
        alarmPushLog.setRegion(json.getStr("region"));
        alarmPushLog.setRemark(json.getStr("remark"));
        alarmPushLog.setShipStatus(json.getStr("shipstatus"));
        alarmPushLog.setSid(json.getStr("sid"));
        alarmPushLog.setSpeed(json.getStr("speed"));
        alarmPushLog.setType(json.getStr("type"));

        //2024-11-18 09:19:17
        String stime = json.getStr("stime");

        alarmPushLog.setTime(LocalDateTime.parse(stime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        JSONArray picurl = json.getJSONArray("picurl");
        alarmPushLog.setImageList(picurl.toList(String.class));

        String videourl = json.getStr("videourl");
        List<String> videoList = new ArrayList<>();
        videoList.add(videourl);
        alarmPushLog.setVideoList(videoList);

        JSONObject other = json.getJSONObject("other");
        alarmPushLog.setCog(other.getStr("_cog"));
        alarmPushLog.setMmsi(other.getStr("_mmsi"));
        alarmPushLog.setShipName(other.getStr("_shipname"));
        alarmPushLog.setSog(other.getStr("_sog"));
        alarmPushLog.setTrueHeading(other.getStr("_trueheading"));
        alarmPushLog.setMyAlarmLat(other.getStr("myalrmlat"));
        alarmPushLog.setMyAlarmLon(other.getStr("myalrmlon"));

        //开始创建报警
        Long alarmId=IdGenerator.SNOW.generate();
        Alarm alarm=new Alarm();
        alarm.setId(alarmId);
        alarm.setPushLevelCode(alarmPushLog.getLevel());
        alarm.setAlarmTime(alarmPushLog.getTime());
        alarm.setSpeed(alarmPushLog.getSpeed());
        alarm.setShipStatus(alarmPushLog.getShipStatus());
        alarm.setLongitude(alarmPushLog.getMyAlarmLon());
        alarm.setLatitude(alarmPushLog.getMyAlarmLat());
        alarm.setImageList(alarmPushLog.getImageList());
        alarm.setVideoList(alarmPushLog.getVideoList());
        alarm.setStatus(AlarmStatusEnum.WAIT);
        alarm.setRegion(alarmPushLog.getRegion());
        alarm.setDutyLevel(alarmPushLog.getDutyLevel());

        //检查事件分组？？


        //检查报警类型
        AlarmType type=new AlarmType();
        type.setCode(alarmPushLog.getType());
        type= typeRepository.getByEntity(type);
        if(type==null){
            //新建报警类型
            type=new AlarmType();
            type.setCode(alarmPushLog.getType());
            type.setName(alarmPushLog.getType());
            type.setEventId(null);
            type.setId(IdGenerator.SNOW.generate());
            typeRepository.create(type);
        }
        alarm.setTypeId(type.getId());

        //检查报警等级
        DataDictionary level=new DataDictionary();
        level.setCode(alarmPushLog.getLevel());
        level.setType(levelTypeId);
        level= dictionaryRepository.getByEntity(level);
        if (level==null){
            //报警等级
            level=new DataDictionary();
            level.setCode(alarmPushLog.getLevel());
            level.setName(alarmPushLog.getLevel());
            level.setType(levelTypeId);
            level.setId(IdGenerator.SNOW.generate());
            dictionaryRepository.create(level);
        }
        alarm.setLevelId(level.getId());

        //检查报警区域
        DataDictionary area=new DataDictionary();
        area.setCode(alarmPushLog.getLevel());
        area.setType(areaTypeId);
        area= dictionaryRepository.getByEntity(area);
        if (area==null){
            throw new BizException("报警区域不存在");
        }
        alarm.setAreaId(area.getId());

        //检查报警原因
        AlarmCause cause=new AlarmCause();
        cause.setCode(alarmPushLog.getReason());
        cause = causeRepository.getByEntity(cause);
        if(cause==null){
            cause=new AlarmCause();
            cause.setCode(alarmPushLog.getReason());
            cause.setName(alarmPushLog.getReason());
            cause.setTypeId(type.getId());
            cause.setId(IdGenerator.SNOW.generate());
            causeRepository.create(cause);
        }
        alarm.setCauseId(cause.getId());


        //检查设备
        Device device=new Device();
        device.setCode(alarmPushLog.getCamNo());
        device = deviceRepository.getByEntity(device);
        if(device==null){
            throw new BizException("设备不存在");
        }
        alarm.setDeviceId(device.getId());

        alarmPushLog.setAlarmId(alarmId);
        alarmPushLogRepository.create(alarmPushLog);
        alarmRepository.save(alarm);
    }

    /**
     * {
     *     areaId : 4,areaName : 左侧舷梯,camNo : 23060022, dutyLevel: 1,level: 1,newalarm: 1,picurl: [http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_1S.jpg,http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_2S.jpg,http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_3S.jpg],reason: 12,region: 0,remark: ,shipstatus: 1,sid: e16ed3aec0a3a4f9,speed: 9.8000001907348633,stime: 2024-11-18 09:19:17,type: 6,videourl: http://10.17.17.199:8008//10.17.17.199:8008//10.17.17.199:8008THE/data/Behavior/20241118/BECLOTHES/RS20241118091909071_14015e2e75a05fd2_A4_1R.jpg,other: {_cog: 222.69999999999999,_mmsi: 413232470,_shipname: 实验室测试,_sog: 10.300000000000001,_trueheading: 228,myalrmlat: 20.053874969482422,myalrmlon: 110.14382171630859}
     */

    public static void main(String[] args) {
        String json = "{ \"areaId\": 4, \"areaName\": \"左侧舷梯\", \"camNo\": \"23060022\", \"dutyLevel\": 1, \"level\": 1, \"newalarm\": 1, \"picurl\": [\"http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_1S.jpg\", \"http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_2S.jpg\", \"http://10.17.17.199:8008/Behavior/20241118/PERSON_SHIPSIDE/RS12_L1_20241118091917118_A4_3S.jpg\"], \"reason\": 12, \"region\": 0, \"remark\": \"\", \"shipstatus\": 1, \"sid\": \"e16ed3aec0a3a4f9\", \"speed\": 9.8000001907348633, \"stime\": \"2024-11-18 09:19:17\", \"type\": 6, \"videourl\": \"http://10.17.17.199:8008//10.17.17.199:8008//10.17.17.199:8008THE/data/Behavior/20241118/BECLOTHES/RS20241118091909071_14015e2e75a05fd2_A4_1R.jpg\", \"other\": { \"_cog\": 222.69999999999999, \"_mmsi\": \"413232470\", \"_shipname\": \"实验室测试\", \"_sog\": 10.300000000000001, \"_trueheading\": 228, \"myalrmlat\": 20.053874969482422, \"myalrmlon\": 110.14382171630859 } }";
        JSONObject jsonObject = new JSONObject(json);
        System.out.println(jsonObject);
        //2024-11-18 09:19:17
        String stime = jsonObject.getStr("stime");
        System.out.println(stime);
        LocalDateTime parse = LocalDateTime.parse(stime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(parse);

    }
}



